home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 16087 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  6.2 KB

  1. Path: keats.ugrad.cs.ubc.ca!not-for-mail
  2. From: c2a192@ugrad.cs.ubc.ca (Kazimir Kylheku)
  3. Newsgroups: comp.lang.ada,comp.lang.c,comp.lang.c++,comp.edu
  4. Subject: Re: ANSI C and POSIX (was Re: C/C++ knocks the crap out of Ada)
  5. Date: 9 Apr 1996 07:38:36 -0700
  6. Organization: Computer Science, University of B.C., Vancouver, B.C., Canada
  7. Message-ID: <4kdspcINN6ct@keats.ugrad.cs.ubc.ca>
  8. References: <JSA.96Feb16135027@organon.com> <dewar.828987544@schonberg> <4kbuebINNrho@keats.ugrad.cs.ubc.ca> <dewar.829048603@schonberg>
  9. NNTP-Posting-Host: keats.ugrad.cs.ubc.ca
  10.  
  11. In article <dewar.829048603@schonberg>, Robert Dewar <dewar@cs.nyu.edu> wrote:
  12. >"This is so deeply entrenched in the realm of common sense that it isn't even
  13. >worth mentioning in a standard document! Nevertheless, I have access to the
  14. >POSIX.1 standard and will look into this."
  15. >
  16. >This seems complete nonsense. There are two possible semantics that ould
  17. >be defined for read (buffer must be at least size of the read argument,
  18. >or buffer must be at least size of data read). Both are easy to specify,
  19. >both are easy to implement. You cannot rely on common sense (especially
  20. >dubious reasoning about kernels and what not that are totally irrelevant
  21. >to the semantic specification). The idea that specs are derived from
  22.  
  23. You are right. This has more to do with those unwritten rules that you
  24. mentioned earlier (my wording, not yours).
  25.  
  26. Expecting that you only have to specify a buffer large enough to hold the
  27. actual data that will be read, while telling the read function that the buffer
  28. is bigger is just not reasonable.
  29.  
  30. Suppose you don't know whether you may or may not lie in specifying the buffer
  31. size, since no documentation explicitly allows it nor prohibits it. Which way
  32. do you make the decision? Which method is safer? Giving a buffer that is as
  33. large as you promise it is, or giving a smaller buffer?
  34.  
  35. There is no telling that even if you know 100% that so many bytes will be read,
  36. the rest of the buffer will not be accessed.
  37.  
  38. >implementations (either by looking at the implementation, or reasoning
  39. >about it with "common sense" or otherwise) is completely unacceptable!
  40.  
  41. You are the one who advocates empirical approaches: in a recent posting you
  42. said that if something works on all the platforms, it is portable regardless
  43. whether it invokes undefined behavior.
  44.  
  45. >(though unfortunately very common, especially when people are writing in 
  46. >a language that does not make a big deal about separating spec and
  47. >implementation details).
  48. >
  49. >My only at-hand sources are K&R, which has nothing whatever to say on 
  50. >the subject, the Zortech C++ reference, which also has nothing to say,
  51. >(both describe read, but say nothing about the buffer length), and
  52. >the Microsoft Runtime Reference which talks about "attempting to
  53. >read n bytes", but is otherwise unclear.
  54. >
  55. >We are after all dealing with a language interface where in practice the
  56. >proper check (whichever it is) cannot be made, because the called routine
  57. >does not know the length of the buffer passed. I think a natural default
  58. >assumption, in the absence of any statement to the contrary, is that the
  59. >bytes are blindly read into the buffer, and disaster strikes if the number
  60. >of bytes read is greater than the buffer length, but otherwise all is well.
  61. >Unless there is a VERY clear statement of semantics to the contrary, I
  62. >don't see how anyone can call code that makes this assumption obviously
  63. >broken.
  64.  
  65. You are right about that, of course. You can't call the code ``obviously
  66. broken'', but I would call the programmer imprudent.
  67.  
  68. >This is of course a rather trivial detail but is instructive with regard
  69. >to the importance of writing precise specs. Kazimir's claim that the spec
  70. >obviously requires that the buffer length match the requested, rather
  71. >than actual length, based on some dubious reasoning about likely 
  72. >implementation models is just the sort of thing that needs to be
  73.  
  74. >eliminated from programming practices. Specs need to be made precise,
  75.  
  76. But here there is a clear lack of precise specs! I'm advocating the _safer_,
  77. more _prudent_ assumption. There is clearly more opportunity to screw up if you
  78. falsely represent your buffer size to a system call or library function.
  79.  
  80. Even if it were OK to do so on every system, the program may later change such
  81. that the hidden assumption is violated. Suddenly, not 68, but 113 bytes come
  82. from the file, for some reason, and the program fails of behaves strangely.
  83. Even all those UNIXes that check against the actual transfer size rather than
  84. buffer size will not necessarily catch this, since the check is usually only
  85. good to the granularity of a page.
  86.  
  87. The current maintainer, of course, doesn't know what hack had been perpetrated
  88. and may be faced with tracing down problems that could have been avoided.
  89.  
  90. >so that a caller knows EXACTLY what the requirements are without having
  91. >to guess, or, worse still, examine the actual implementation code.
  92.  
  93. I agree. I was dismayed when I was not able to find a definitive answer in the
  94. POSIX.1 standard itself. These sorts of things should be specified so that the
  95. programmers don't have to rationalize about what is likely to be safer. 
  96.  
  97. Here is my ``dubious'' reasoning laid out step by step, so criticize at will:
  98.  
  99. 1.    In the C language, the size of an object has a specific meaning. If I
  100.     malloc 100 bytes, or declare 100 bytes in static or automatic storage,
  101.     the size of that object is not 101, not 1000, but 100 bytes.
  102.  
  103.     (Granted, the third argument of read() is not usually referred to as
  104.     the _size_ of the object pointed at by the second argument, but as a
  105.     _count_ of bytes to be read into the buffer. It does have a size_t type
  106.     which is used in ANSI C to hold the sizes of objects, and is the
  107.     return type of the sizeof operator).
  108.  
  109. 2.    No documentation has ever explicitly stated that the argument may be
  110.     greater than the actual size of the object to which a pointer can
  111.     be given.
  112.  
  113. 3.    In choosing between two alternatives, choose the safer one, all else
  114.     being equal.
  115.     
  116. 4.    Even if the apparently less safe alternative is actually safe, it
  117.     depends on preconditions in the program which may change, namely
  118.     assumptions about how many bytes are left in the particular file, pipe
  119.     or whatever. This will could cause problems in the maintenance cycle
  120.     of the software.
  121. -- 
  122.  
  123.